package com.simple.apt.processor;

import cn.hutool.core.util.StrUtil;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Objects;
import java.util.Set;

/**
 * @author FanXing
 * @date 2023年01月25日 0:36
 */
public abstract class BasicProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (TypeElement annotationElement : annotations) {
            Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotationElement);
            for (Element element : annotatedElements) {
                TypeElement annotatedClass = (TypeElement) element;
                String className = annotatedClass.getSimpleName().toString();
                String packageStr = StrUtil.subBefore(annotatedClass.getQualifiedName().toString(), ".", true);

                String builderClassName = initBuilderClassName(annotatedClass, className);
                String builderQualifiedClassName = packageStr + "." + builderClassName;
//                检查文件是否已存在
                TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(builderQualifiedClassName);
                if (Objects.nonNull(typeElement)) continue;

                JavaFileObject builderFile = null;
                try {
                    builderFile = processingEnv.getFiler().createSourceFile(builderQualifiedClassName);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                try (PrintWriter out = new PrintWriter(builderFile.openWriter())) {
                    String builderClassSrc = initBuilderClassSrc(annotatedClass, packageStr, builderClassName, className);
                    out.println(builderClassSrc);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return false;
    }

    protected abstract String initBuilderClassSrc(TypeElement annotatedClass, String packageStr, String builderClassName, String entityClassName);

    protected abstract String initBuilderClassName(TypeElement annotatedClass, String className);

}
